﻿/* Copyright (c) 2015 Slava Naumenko - http://m4w.codeplex.com */

using Microsoft.SharePoint;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Web.Services;

namespace M4W.ASM.Services
{
    [WebService(Namespace = "M4W.ASM.Services")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.Web.Script.Services.ScriptService]
    [System.ComponentModel.ToolboxItem(false)]
    public class Group : System.Web.Services.WebService
    {
        [WebMethod]
        public string Create(string Group, string Description, string Owner, string Permissions)
        {
            string result = "";
            try
            {
                GroupCreate.Invoke(Group, Description, Owner, Permissions);

                result = "Group '" + Group + "' created.";
            }
            catch (Exception ex)
            {
                result = ex.Message.ToString();
            }
            return result;
        }

        [WebMethod]
        public string Delete(string Group)
        {
            string result = "";
            try
            {
                GroupDelete.Invoke(Group);

                result = "Group '" + Group + "' deleted.";
            }
            catch (Exception ex)
            {
                result = ex.Message.ToString();
            }
            return result;
        }

        [WebMethod]
        public string UsersAdd(string Group, string Users)
        {
            string result = "";
            try
            {
                GroupManageUsers.Invoke(Group, Users, "add");

                result = "User(s) '" + Users + "' added to '" + Group + "'.";
            }
            catch (Exception ex)
            {
                result = ex.Message.ToString();
            }
            return result;
        }

        [WebMethod]
        public string UsersRemove(string Group, string Users)
        {
            string result = "";
            try
            {
                GroupManageUsers.Invoke(Group, Users, "remove");

                result = "User(s) '" + Users + "' removed from '" + Group + "'.";
            }
            catch (Exception ex)
            {
                result = ex.Message.ToString();
            }
            return result;
        }
    }

    // Invocations

    internal static class GroupCreate
    {
        internal static void Invoke(string Group, string Description, string Owner, string Permissions)
        {
            string curl = Helper.GetCurrentUrl();

            using (SPSite site = new SPSite(curl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    web.AllowUnsafeUpdates = true;

                    SPUser user = (SPUser)null;
                    if (Owner == "")
                    {
                        user = web.EnsureUser("System Account");
                    }
                    else
                    {
                        try
                        {
                            user = web.EnsureUser(Owner);
                        }
                        catch (Exception)
                        {
                        }
                    }

                    if (user != null)
                    {
                        web.SiteGroups.Add(Group, (SPMember)user, (SPUser)null, Description);
                    }
                    else
                    {
                        web.SiteGroups.Add(Group, (SPMember)web.SiteGroups[Owner], (SPUser)null, Description);
                    }

                    SPGroup group = Enumerable.First<SPGroup>(Enumerable.Where<SPGroup>(Enumerable.OfType<SPGroup>((IEnumerable)web.SiteGroups), (Func<SPGroup, bool>)(gn => gn.Name == Group)));

                    if (!string.IsNullOrEmpty(Permissions))
                    {
                        StringReader stringReader = new StringReader(Permissions);
                        SPRoleAssignment roleAssignment = new SPRoleAssignment((SPPrincipal)group);
                        string index;
                        while ((index = stringReader.ReadLine()) != null)
                        {
                            SPRoleDefinition roleDefinition = web.RoleDefinitions[index];
                            roleAssignment.RoleDefinitionBindings.Add(roleDefinition);
                        }
                        web.RoleAssignments.Add(roleAssignment);
                    }

                    if (Owner == "")
                    {
                        group.Owner = group;
                        group.Update();
                    }

                    web.AllowUnsafeUpdates = false;
                }
            }
        }
    }

    internal static class GroupDelete
    {
        internal static void Invoke(string Group)
        {
            string curl = Helper.GetCurrentUrl();

            using (SPSite site = new SPSite(curl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    web.AllowUnsafeUpdates = true;

                    web.SiteGroups.Remove(Group);

                    web.AllowUnsafeUpdates = false;
                }
            }
        }
    }

    internal static class GroupManageUsers
    {
        internal static void Invoke(string Group, string Users, string mode)
        {
            string curl = Helper.GetCurrentUrl();

            using (SPSite site = new SPSite(curl))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    web.AllowUnsafeUpdates = true;

                    SPGroup group = web.SiteGroups[Group];

                    string[] coll = Users.Trim().Split(';');
                    foreach (string username in coll)
                    {
                        if (username != "")
                        {
                            SPUser user = web.EnsureUser(@username.Trim());
                            if (user != null)
                            {
                                if (group != null)
                                {
                                    if (mode == "add")
                                    {
                                        group.AddUser(user);
                                    }
                                    else if (mode == "remove")
                                    {
                                        group.RemoveUser(user);
                                    }
                                }
                            }
                        }
                    }

                    web.AllowUnsafeUpdates = false;
                }
            }
        }
    }
}